﻿
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Stock.Core.Services;
using System.Reflection;
using System;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
using Web.Middlewares;
using Stock.Core;
using Web;
using Web.Filters;
using Microsoft.IdentityModel.Tokens;
using Hangfire;
using Stock.Core.Common;
using Stock.Core.MongoDB;
using Stock.Model;

namespace Microsoft.eShopWeb
{
	/// <summary>
	/// Startup
	/// </summary>
	public class Startup
	{
		public IContainer ApplicationContainer { get; private set; }

		/// <summary>
		/// Initializes a new instance of the <see cref="T:Microsoft.eShopWeb.Startup"/> class.
		/// </summary>
		/// <param name="env">Env.</param>
		public Startup(IHostingEnvironment env)
		{
			var builder = new ConfigurationBuilder()
			    .SetBasePath(env.ContentRootPath)
			    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
			    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
			    .AddEnvironmentVariables();
			Configuration = builder.Build();
		}

        /// <summary>
        /// configuration.
        /// </summary>
        /// <value>The configuration.</value>
		public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            // 添加动态压缩
            services.AddResponseCompression();

            // 添加加密码组件
            //services.AddDataProtection();

            // 配置文件加载
            services.Configure<LogSettings>(Configuration.GetSection("LogSettings"));
            services.Configure<RedisOptions>(Configuration.GetSection("Redis"));
            //services.Configure<DBSettings>(Configuration.GetSection("DBSettings"));
            services.Configure<MongoOptions>(Configuration.GetSection("MongoOptions"));
            services.AddMvc(option =>
            {
                option.Filters.Add(typeof(WebApiTrackerAttribute));
            });

            // 跨域
            services.AddCors(options => options.AddPolicy("myCors",
        p => p.WithOrigins("http://a.example.com", "http://*.avatar-edu.cn").AllowAnyMethod().AllowAnyHeader()));


            //// 添加redis做为session
            //services.AddDistributedRedisCache(option =>
            //{
            //    //redis 数据库连接字符串
            //    option.Configuration = Configuration.GetConnectionString("RedisConnection");
            //    //redis 实例名
            //    option.InstanceName = "master";
            //});
            //services.AddSession();


            ////配置任务插件
            //services.AddHangfire(r =>
                                 ////r.UseSqlServerStorage(Configuration["ConnectionString"])
                                 //r.UseRedisStorage(Configuration.GetConnectionString("RedisConnection")));

            // help
            services.AddSwaggerGen();
            services.ConfigureSwaggerGen(options =>
            {
                options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info
                {
                    Version = "v1",
                    Title = "My Web Application",
                    Description = "RESTful API for My Web Application",
                    TermsOfService = "None"
                });
                options.IncludeXmlComments(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath,
            "Web.xml")); // 注意：此处替换成所生成的XML documentation的文件名。
                options.DescribeAllEnumsAsStrings();
            });

            // autofac
            var builder = new ContainerBuilder();

          
            //builder.RegisterType<RedisProvider>().As<IRedisProvider>().SingleInstance();
            builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();
            //builder.Register(m => new UnitOfWork(Configuration["DBSettings:DBType"], Configuration["DBSettings:ConnectionString"]))
                   //.As<IUnitOfWork>().InstancePerLifetimeScope();

            builder.AddUnitOfWork(Configuration["DBSettings:DBType"], Configuration["DBSettings:ConnectionString"]);
	
            builder.UseStockCore(()=>{ return true; });

            builder.Populate(services);
            this.ApplicationContainer = builder.Build();
            return new AutofacServiceProvider(this.ApplicationContainer);

        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Catalog/Error");
            }
            app.UseErrorHandling();
            app.UseStaticFiles();
            //app.UseExecuteTime();
            app.UseResponseCompression();
            //app.UseSession();
            //app.UseHangfireServer();
            //app.UseHangfireDashboard();

            app.UseAuth();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
            name: "default",
            template: "{controller=Web}/{action=Login}/{id?}");


                routes.MapRoute(
            name: "api",
            template: "api/{controller}/{action}/{id?}",
            defaults: new { controller = "Home", action = "Index" });


            });

            app.UseSwagger();
            app.UseSwaggerUi();



            loggerFactory.AddProvider(new MyFilteredLoggerProvider(this.ApplicationContainer));

            app.UseCors("myCors");

            //app.UseCookieAuthentication(new CookieAuthenticationOptions
            //{
            //    AuthenticationScheme = "member",    // 验证方案名
            //    AutomaticAuthenticate = true,   // 是否自动启用验证
            //    LoginPath = "/account/login",    // 登录地址
            //                                     //CookieDomain = "abc.com",       // 验证域
            //    CookieName = "auth",             // Cookie 名称
            //    CookiePath = "/",               // Cookie 路径
            //    ExpireTimeSpan = TimeSpan.FromDays(3),  // 过期时间
            //    SlidingExpiration = true,   // 是否在过期时间过半的时候，自动延期
            //    CookieHttpOnly = true       // 是否允许客户端Js获取。默认True，不允许。
            //});




            //Seed Data
            //CatalogContextSeed.SeedAsync(app, loggerFactory)
            //.Wait();


            // If you want to dispose of resources that have been resolved in the
            // application container, register for the "ApplicationStopped" event.
            appLifetime.ApplicationStopped.Register(() => this.ApplicationContainer.Dispose());
        }
	}
}
